home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / zapem-0.000 / zapem-0 / zapem / sprite.cc < prev    next >
C/C++ Source or Header  |  1995-06-03  |  7KB  |  383 lines

  1. /*    Copyright Alex Hornby 1994/1995. All rights reserved.
  2.      See file README for details
  3. */
  4.  
  5. /* C++ code for sprite block copy wrapper */
  6.  
  7. #include <SLList.h>
  8. #include <assert.h>
  9. #include <vga.h>
  10. #include <iostream.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "btypes.h"
  15. #include "palette.h"
  16. #include "sprite.h"
  17. #include "asmblock.h"
  18. #include "gif.h"
  19. #include "alopen.h"
  20.  
  21. extern Palette gamepal;
  22.  
  23. /* Static data members */
  24. SLList<Sprite*> Sprite :: vlist;
  25. SLList<Sprite*> Sprite :: appearlist;
  26. SLList<Sprite*> Sprite :: disappearlist;
  27.  
  28. /***************************************************************************
  29.             LET THE FUNCTIONS BEGIN!
  30. ****************************************************************************/
  31.  
  32. Sprite::~Sprite() 
  33. {
  34.     if( backmem!=0) delete backmem;
  35.     if (visibleflag==true) setVisible(false);
  36. }
  37.  
  38. Sprite::Sprite() : Animation(), Screen() 
  39. {
  40.     visibleflag=false;
  41.     backmem=0;
  42. }
  43.  
  44. void
  45. Sprite::copy( const Sprite& s)
  46. {
  47.     xp=s.xp;
  48.     yp=s.yp;
  49.     oldxp=s.oldxp;
  50.     oldyp=s.oldyp;
  51.     deltax=s.deltax;
  52.     deltay=s.deltay;
  53.     setVisible(s.getVisible());
  54.  
  55.     if(backmem!=0) 
  56.         delete [] backmem;
  57.     backmem=new byte [ByteLength];
  58.     if(s.backmem!=0)
  59.         memcpy(backmem, s.backmem, ByteLength);
  60.  
  61. Sprite::Sprite( const Sprite& s) : Animation(s), Screen(s)
  62. {
  63.     copy(s);
  64. }
  65.  
  66. Sprite&
  67. Sprite::operator=( const Sprite& s) 
  68. {
  69.     if( &s != this)
  70.     {
  71.         Animation::operator=(s);
  72.         Screen::operator=(s);
  73.         copy(s);
  74.     }
  75.     return *this;
  76. }
  77.  
  78. /* Load the single sprite gif file int sprite bank slot */ 
  79. /* Yuck! */
  80. void
  81. Sprite :: gifLoadAndCut(char *filename, int slot)
  82. {
  83.     FILE *fp=alopen(filename, "rb");
  84.     Gif gif;
  85.     Palette gifpal;
  86.     gif.Load(fp);
  87.     
  88.     gifpal.scan(gif.getPtr(), gif.getWidth()*gif.getHeight());
  89.         gif.SetPalette(gifpal);
  90.         gamepal.remap(gif.getPtr(), gif.getWidth()*gif.getHeight() , gifpal);
  91.  
  92.     // Save the old screen settings
  93.     pixel *oldgmem=getGraphMem();
  94.     int oldswidth=getScreenWidth();
  95.     int oldsheight=getScreenHeight();
  96.     // Set the screen up to the same size as the picture
  97.     setGraphMem(gif.getPtr());
  98.     setScreenWidth(gif.getWidth());
  99.     setScreenHeight(gif.getHeight());
  100.  
  101.     // Cut the sprite
  102.     Cut(0, 0, gif.getWidth(), gif.getHeight(), slot);
  103.     // Restore the screen settings
  104.     setGraphMem(oldgmem);
  105.     setScreenHeight(oldsheight);    
  106.     setScreenWidth(oldswidth);
  107. }
  108.  
  109. /* Have we collided with something? */
  110. bool
  111. Sprite :: collide(const Sprite& s)
  112. {
  113.     int xd=s.getXp()-getXp();
  114.     int yd=s.getYp()-getYp();
  115.  
  116.     if( (xd< getWidth() && xd > -s.getWidth() ) && 
  117.         (yd< getHeight() && yd > -s.getHeight()) )
  118.         return true;
  119.     else
  120.         return false;     
  121. }
  122.  
  123. void
  124. Sprite :: setSlot(int slot)
  125. {
  126.         assert(slot<MAXFRAME);
  127.         assert(slot>=0);
  128.         curslot=slot;
  129.         blockmem=sprbank[slot].block;
  130.         maskmem=sprbank[slot].mask;
  131.         width=sprbank[slot].width;
  132.         height=sprbank[slot].height;
  133.         ByteLength=sprbank[slot].ByteLength;
  134. }
  135.  
  136. void 
  137. Sprite :: appear(void)
  138. {
  139.     Sprite *x=this;
  140.     appearlist.append(x);
  141. }
  142.  
  143. void 
  144. Sprite :: disappear(void)
  145. {
  146.     Sprite *x=this;
  147.     disappearlist.append(x);
  148. }
  149.  
  150. void
  151. Sprite :: setVisible( bool v)
  152. {
  153.     if( v==true)    
  154.     {
  155.         if(visibleflag==false)
  156.         {
  157.             visibleflag=true;        
  158.             vlist.append(this);
  159.         }
  160.     }
  161.     else
  162.     {
  163.         Pix here, prev=0;
  164.  
  165.         if(visibleflag==true)
  166.         {
  167.             for(here=vlist.first(); here!=0; vlist.next(here))
  168.             {
  169.                 if(vlist(here)==this)
  170.                 {
  171.                     if(here==vlist.first())
  172.                         vlist.del_front();
  173.                     else
  174.                         vlist.del_after(prev);
  175.                     here=0;
  176.                 }    
  177.                 prev=here;                
  178.             }
  179.         }
  180.     visibleflag=false;
  181.     }
  182. }
  183.  
  184. void 
  185. Sprite :: Cut ( uint32 x1, uint32 y1, uint32 xw, uint32 yw, int slot)
  186. {
  187.     curslot=slot;
  188.     /* Make the slot equal our new graphic. There should really be 
  189.        some checking to see if the slot is already in use */
  190.     sprbank[slot].width=width=xw;
  191.     sprbank[slot].height=height=yw;
  192.     sprbank[slot].ByteLength=ByteLength=xw*yw;
  193.     xp=x1;yp=y1;
  194.  
  195.     /* if memory in use then free it. This is extremely dodgy! */
  196.     if( backmem!=0 ) delete backmem; 
  197.  
  198.     /* reserve block memory */
  199.     blockmem=new byte [ByteLength];
  200.     maskmem=new byte [ByteLength];
  201.     backmem=new byte [ByteLength];
  202.     sprbank[slot].block=blockmem;
  203.     sprbank[slot].mask=maskmem;
  204.  
  205.     /* call assembly routines */
  206.     cutblocknew( getGraphMem()+x1+(y1*getScreenWidth()), blockmem, getScreenWidth(), width, height);
  207.     cutblocknew( getGraphMem()+x1+(y1*getScreenWidth()), backmem, getScreenWidth(), width, height);
  208.     MakeMask();
  209. }
  210.  
  211. void
  212. Sprite :: MakeMask(byte maskcolour)
  213. {
  214.     uint32 count;
  215.     byte *maskptr, *blockptr;
  216.  
  217.     maskptr=maskmem;
  218.     blockptr=blockmem;
  219.     for( count=0; count<ByteLength; count++)
  220.     {
  221.         if(*blockptr==maskcolour)
  222.             *maskptr=255;
  223.         else
  224.             *maskptr=0;
  225.         maskptr++;
  226.         blockptr++;
  227.     }
  228. }
  229.  
  230. void
  231. Sprite :: Recut( uint32 x1, uint32 y1)
  232. {
  233.     /* call assembly routine */
  234.     cutblock( getGraphMem()+x1+(y1*getScreenWidth()), blockmem, width, height); 
  235.     MakeMask();
  236. }
  237.  
  238. void
  239. Sprite :: Paste( uint32 x1, uint32 y1)
  240. {
  241.     /* Straight into the assembly bit */
  242.     pasteblock( blockmem, getGraphMem()+x1+(y1*getScreenWidth()), width, height );
  243. }
  244.  
  245. void
  246. Sprite :: getBack( uint32 x1, uint32 y1)
  247. {
  248.     xp=oldxp=x1;yp=oldyp=y1;
  249.  
  250.     /* get new background */
  251.     if(backmem==0) backmem=new byte[ByteLength];
  252.     cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
  253. }
  254.  
  255. void
  256. Sprite :: ReplaceAll(void)
  257. {
  258.     Pix cur, n;    // n is needed because of animation can cause NULL pix
  259.  
  260.     cur=vlist.first();
  261.     assert(cur!=0);
  262.  
  263.     while( cur!=0 )
  264.     {
  265.         vlist(cur)->fixBack();
  266.         n=cur;
  267.         vlist.next(n);
  268.         if( vlist(cur)->getAnim()==true)
  269.             vlist(cur)->doAnim();
  270.         cur=n;
  271.     }
  272.  
  273.     cur=disappearlist.first();
  274.     while(cur!=0)
  275.     {
  276.         disappearlist(cur)->setVisible(false);
  277.         disappearlist.next(cur);
  278.     }
  279.  
  280.     while(!disappearlist.empty())
  281.     {
  282.         disappearlist.remove_front();
  283.     }
  284. }
  285.  
  286. void
  287. Sprite :: PasteAll(void)
  288. {
  289.     Pix cur=vlist.first();
  290.     while( cur!=0 )
  291.     {
  292.         vlist(cur)->Transpaste();
  293.         vlist.next(cur);
  294.     }
  295. }
  296.  
  297. void
  298. Sprite :: UpdateAll(void)
  299. {
  300.     ReplaceAll();
  301.     PasteAll();    
  302. }
  303.  
  304. void
  305. Sprite :: hideAll(void)
  306. {
  307.     Pix cur, n;    // n is needed because of animation can cause NULL pix
  308.  
  309.     cur=vlist.first();
  310.  
  311.     while( cur!=0 )
  312.     {
  313.         n=cur;
  314.         vlist.next(n);
  315.         vlist(cur)->setVisible(false);
  316.         cur=n;
  317.     }
  318. }
  319.  
  320. void
  321. Sprite :: Update( int x1, int y1)
  322. {
  323.     xp=x1;yp=y1;
  324.  
  325.     // replace old bit
  326.     pasteblock( backmem, getGraphMem()+oldxp+(oldyp*getScreenWidth()), width, height );
  327.  
  328.     // get new background
  329.     cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
  330.  
  331.     // display sprite
  332.     Transpaste();
  333. }
  334.  
  335. void
  336. Sprite :: Transpaste( void)
  337. {
  338.     /*
  339.     andpasteblock( maskmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
  340.     xorpasteblock( blockmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
  341.     */
  342.     transpasteblock( blockmem, maskmem, getGraphMem()+xp+(yp*getScreenWidth()), width, height );
  343.     oldxp=xp;oldyp=yp;
  344. }
  345.  
  346. void 
  347. Sprite::getAll()
  348. {
  349.     Pix cur=appearlist.first();
  350.     while(cur!=0)
  351.     {
  352.         appearlist(cur)->setVisible(true);
  353.         appearlist(cur)->getBack();
  354.         appearlist.next(cur);
  355.     }
  356.     while(!appearlist.empty())
  357.     {
  358.         appearlist.remove_front();
  359.     }
  360.     
  361.     cur=vlist.first();
  362.     while( cur!=0 )
  363.     {
  364.         vlist(cur)->CutBack();
  365.         vlist.next(cur);
  366.     }
  367. }
  368.  
  369. void
  370. Sprite :: fixBack( void )
  371. {
  372.     // replace old bit
  373.     pasteblock( backmem, getGraphMem()+oldxp+(oldyp*getScreenWidth()), width, height );
  374. }
  375.  
  376. void 
  377. Sprite :: CutBack( void)
  378. {
  379.     // get new background
  380.     cutblock( getGraphMem()+xp+(yp*getScreenWidth()),backmem, width, height );
  381. }
  382.